home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
VGA_VUL1.ZIP
/
BOARDZ.ASM
next >
Wrap
Assembly Source File
|
1995-06-17
|
16KB
|
378 lines
;==============================================================================;
; ;
; Assembler program by Vulture. ;
; This program scrolls a text and displays a 3d-starfield. ;
; It's a BBS advertisement. ;
; ;
; Current Date: 13-2-95 Vulture ;
; ;
;==============================================================================;
DOSSEG ; Sort the segment using DOS standard CODE DATA STACK
.MODEL SMALL ; Code is smaller than 64kB (code & data)
.STACK 200h ; Specify stack
.286 ; Allow 80286 instructions
.CODE ; Codesegment starts here
JUMPS ; Let Tasm handle out of range jumps
ASSUME CS:@CODE ; cs points to codesegment
; === DATA ===
INCLUDE Font.dat ; File with font data
INCLUDE Numbers.dat ; Include 500 random numbers between -200 and 200
Message DB 13,10,"Code by Vulture.",13,10,"$" ; Important message :)
Star_Struc STRUC ; Format of star (like a record in Pascal)
X DW 0 ; X-position of star
Y DW 0 ; Y-position of star
Z DW 0 ; Z-position of star
Old DW 0 ; Where to erase old star
Col DB 0 ; Color of star
Star_Struc ENDS
StarStrucSize = 9 ; Number of bytes per entry ( 4 wordz and a byte )
ScreenWidth EQU 320 ; Obvious
ScreenHeight EQU 200 ; Obvious
MaxStars EQU 250 ; Maximum number of stars
MaxNumbers EQU 500 ; Number of random numbers defined
MaxZ EQU 4096 ; StartZvalue for all stars
MinZ EQU 0 ; If Z = 0 then star is dead
XIndex DW 250 ; Index to X-numbers
YIndex DW 125 ; Index to Y-numbers
WarpSpeed DW 20 ; Speed of stars
NumActive DW 0 ; Number of stars active
Stars Star_Struc MaxStars DUP (?) ; Array of star-records
Palette DB 0,0,0 ; Palette info for first 5 colors (font)
DB 0,0,0
DB 52,0,0
DB 42,0,0
DB 32,0,0
DB 0,0,0 ; Base color black => R,G,B
i=15 ; 16 grey shades
REPT 16
DB 3*i,3*i,3*i
i=i-1
ENDM
PaletteArray DB 768 DUP (?) ; Array to hold the palette
Text DB 'if u wanna experience some cewl boardz in the netherlands '
DB 'call firehouse 058-661590 detonator 05111-4307 or '
DB 'mark of cain 058-672111 cu around. . . . . .'
DB ' ',0 ; Text to scroll
Order DB 'abcdefghijklmnopqrstuvwxyz0123456789-. ' ; Order of characters
; === PROCEDURES ===
SetVGA PROC NEAR ; Get into VGA mode
mov ax,0013h ; Set the videomode 320*200*256
int 10h ; Call VID interrupt
ret
SetVGA ENDP
SetText PROC NEAR ; Get into character mode
mov ax,0003h ; Set 80x25x16 char mode
int 10h ; Call VID interrupt
ret
SetText ENDP
WaitVrt PROC NEAR ; Waits for vertical retrace to reduce "snow"
mov dx,3dah
Vrt:
in al,dx
test al,8
jnz VRT ; Wait until Verticle Retrace starts
NoVrt:
in al,dx
test al,8
jz NoVRT ; Wait until Verticle Retrace ends
ret ; Return to main program
WaitVrt ENDP
SavePalette PROC NEAR ; Saves entire palette in array
cli ; Disable interrupts
mov bp,offset PaletteArray ; Point to start of array
mov cx,768 ; Save all R,G,B registers
mov dx,03c7h ; Read register
mov al,0 ; Start at 0
out dx,al ; Write to port
mov dx,03c9h ; Read data register
Grab:
in al,dx ; Read value from port
and al,3fh ; Mask of upper 2 bits
mov byte ptr [bp],al ; Store the value in aray
inc bp ; Point to the next one
loop Grab ; Loop until cx = 0
sti ; Enable interrupts
ret ; Return to main program
SavePalette ENDP
FadeOut PROC NEAR ; Fades screen to black
cli ; Disable interrupts
mov bp,offset PaletteArray ; Point to start of array
mov cx,64 ; Repeat 64 times (0..63)
OneCycle:
mov bx,0 ; Set counter
Decrease:
cmp byte ptr [bp],0 ; Is it 0 already ?
je Fading ; Yep => Do the next
dec byte ptr [bp] ; Nope => Decrease by one
Fading:
inc bp ; Point to next value
inc bx ; Increase counter
cmp bx,768 ; Have we reached the end ?
jl Decrease ; No => Do another one
push cx ; Save 1st loop counter
call WaitVrt ; Wait for retrace
sub bp,768 ; Point to start
mov bx,0 ; Reset counter
mov cx,768 ; Do all colors
mov dx,03c8h ; Write register
mov al,0 ; Start at 0
out dx,al ; Write to port
inc dx ; Writing => 03c8h + 1 = 03c9h
WriteAll:
mov al,byte ptr [bp] ; Store value in al
out dx,al ; Give it to the VGA
inc bp ; Point to next one
inc bx ; Increase counter
loop WriteAll ; Loop while cx > 0
pop cx ; Restore 1st loop counter
sub bp,768 ; Point to start
loop OneCycle ; Loop while cx > 0
sti ; Enable interrupts
ret ; Return to main program
FadeOut ENDP
CalcStar PROC NEAR
pusha ; Put all registers on stack
mov si,0 ; si points to first star
StartCalc: ; Start searching for empty slots
cmp [NumActive],MaxStars ; Check for room
jae NoEmptySpace ; No room => exit
SearchSlot:
cmp word ptr [Stars.Z+si],MinZ ; If Z = 0 then slot is empty
je FillSlot
add si,StarStrucSize ; si points to next star
cmp si,StarStrucSize*MaxStars ; Have we done entire array ?
jb SearchSlot ; No => search again
jmp NoEmptySpace ; Yes => exit
FillSlot:
mov di,[XIndex] ; Grab Xindex and put it in di
add di,di ; Make WORD index
mov ax,[Numbers+di] ; Get the number
shl ax,3 ; Multiply by 8
mov [Stars.X+si],ax ; Save the number
mov di,[YIndex] ; Do the same for Y
add di,di
mov ax,[Numbers+di]
shl ax,3
mov [Stars.Y+si],ax
mov [Stars.Z+si],MaxZ ; Give star the Z offset
mov al,0 ; Also give it basecolor 0 (black)
mov [Stars.Col+si],al ; Store the color
inc [NumActive] ; Increase star counter
inc [XIndex] ; Increase the X index
cmp [XIndex],MaxNumbers ; Have we reached the end of the list?
jb XindNotMax ; No => continue
mov [XIndex],0 ; Yes => go to start of list
XindNotMax:
inc [YIndex] ; Increase the Y index
cmp [YIndex],MaxNumbers ; Have we reached the end of the list?
jb StartCalc ; No => continue
mov [YIndex],0 ; Yes => go to start of list
NoEmptySpace:
popa ; Restore all registers
ret ; Return to main program
CalcStar ENDP
ShowStars PROC NEAR
pusha ; Save all registers
mov si,0 ; si points to first record
ShowLoop:
mov cx,[Stars.Z+si] ; Grab Z value of star
cmp cx,0 ; If Z = 0 then exit
je ContinueStar ; Do the next star
mov di,[Stars.Old+si] ; Get old position of star
mov byte ptr es:[di],0 ; Erase the old star
mov ax,[Stars.X+si] ; Grab X value of star
mov dx,256 ; Multiply X with 256
imul dx
idiv cx ; Divide by Z
add ax,ScreenWidth/2 ; Add 160 to center it on the screen
mov di,ax ; di = X
cmp di,ScreenWidth ; Is the star in range ?
jae TermStar ; No => Do next star
mov ax,[Stars.Y+si] ; Grab an Y value
mov dx,256 ; Multiply Y with 256
imul dx
idiv cx ; Divide by Z (a bit slow but who carez)
add ax,ScreenHeight/2 ; Add 100 to center it on the screen
cmp ax,ScreenHeight ; Is the star in range ?
jae TermStar ; No => Do next star
cmp ax,90 ; Do not affect scroller
jl InRange
cmp ax,100 ; Text scrolls between 90 & 100
ja InRange
jmp TermStar ; Star affects scroller so terminate it
InRange:
imul ax,ScreenWidth ; ax = Y * ScreenWidth
add di,ax ; di = X + (Y * 320)
mov [Stars.Old+si],di ; Save the position
add ch,cs:[Stars.Col+si] ; Divide Z by 256 & add basecolor 0
mov al,ch ; Move color into al
add al,5d ; Add 5 to avoid fontcolors
mov byte ptr es:[di],al ; Place the dot on the screen
mov ax,[WarpSpeed]
sub cx,ax ; Decrease Z with WarpSpeed
mov [Stars.Z+si],cx ; Save the new Z
jmp ContinueStar ; Do the next star
TermStar:
mov [Stars.Z+si],MinZ ; Set Z to 0 => Star is terminated
dec [NumActive] ; Decrease number of active stars
ContinueStar:
add si,StarStrucSize ; si points to next record
cmp si,StarStrucSize*MaxStars ; Reached end of array ?
jb ShowLoop ; Continue with next star
popa ; Restore all registers
ret ; Return to main program
ShowStars ENDP
; === MAIN PROGRAM ===
START:
cli ; Clear interrupt flag
call SetVGA ; Get in GFX-mode
; === Set the palette ===
mov ax,cs ; Move CS into AX
mov es,ax ; es points to codesegment
mov ax,1012h ; Select write palette function
mov bx,0 ; Start at color 0
mov cx,23 ; Write 23 colors
mov dx,offset Palette ; es:dx points to palette data
int 10h ; Call VID interrupt & set palette
call SavePalette ; And save palette into array
; === Initialize pointers ===
mov ax,0a000h
mov es,ax ; es points to VGA
mov ax,cs
mov ds,ax ; ds points to codesegment (data)
; === Start scroll ===
Reset:
lea si,Text ; si points to start of Text
Mainthing: ; Main loop
lodsb ; Load a character in al (si increased)
cmp al,0 ; Have we reached the end of da text ?
je Reset ; Yep => Start over
push si ; Save character-offset on stack
mov bx,ax ; Save the character into bx
mov cx,0 ; Set character-counter for position in font
lea si,Order ; si points to offset Order
Again:
lodsb ; Load the order-character (abcdef etc...)
cmp ax,bx ; Is it da same letter/character ?
je Found ; Yeah => Found it. . .
inc cx ; Nope => Increase character-counter
jmp Again ; Compare with next character
Found:
mov ax,8 ; 7 pixels + black pixel = 8 pixels
mul cx ; ax=ax*cx (e.g: E := 4 * 10;)
mov bx,4 ; Draw 4 * 2 vertical lines
Hloop:
lea si,Font ; si points to start of Font
add si,ax ; si now points to character
mov di,320*91 ; di points to startposition on VGA
mov cx,9 ; Write 9 horizontal
Vloop:
push cx ; Save first loop-counter
mov cx,2 ; Draw 2 new horizontal pixels
repz movsb ; And go !
add di,318 ; Point to next location on VGA
add si,318 ; Point to next source-location
pop cx ; Restore loop-counter
loop Vloop ; Loop 9 times
; === Scroll the text and improve stars ===
push ds ax ; Save pointer to character + ds
mov ax,0a000h ; VGA-segment
mov ds,ax ; ds points to VGA
mov si,320*90+2 ; Destination offset
mov di,320*90 ; Source offset
mov cx,10*320 ; Repeat factor => Number of bytes to copy
rep movsb ; And go ! (Hint: why not use words instead)
mov di,320*101 ; On some slow VGA-cards we have to plot
mov cx,5 ; 5 black pixels just below the scroller
mov al,0 ; on the left on the screen. Erase this
rep stosb ; code to see what I mean.
call WaitVrt ; Wait for vertical retrace
call CalcStar ; Calculate new stars
call ShowStars ; Show all stars on VGA
; === Want to quit ? ===
in al,60h ; Was ESCAPE pressed ?
cmp al,1
je QuitNow ; If so, quit now. . .
; === No quit ? then continue ===
pop ax ds ; Restore pointer to character + ds
add ax,2 ; And add 2 to point to next 2 vertical lines
dec bx ; Decrease line-counter
jnz Hloop ; If it's 0 then jump
pop si ; Restore character-offset to do next char
jmp Mainthing ; And start over again
QuitNow: ; Quit everything
call FadeOut ; Fade da screen to black
call SetText ; Get in TXT-mode
mov ax,cs
mov ds,ax ; ds points to codesegment (data)
lea dx,Message ; Load offset message
mov ah,9 ; Select function 9 (print string)
int 21h ; Print the message
mov ax,4c00h ; Quit program
int 21h
END START ; End Of C<><>L Program !!!
; Code by Vulture.
; Thanx to Draeden of VLA for example code.
; Don't be lame. Don't just rip the code.
; Give credit where it should be. I did.
; See ya in the next release.